////////////////////////////////////////////////////////////////////////
// This file is part of the simpleSID framework 
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
//
// Copyright (c)Richard White, 2009
// See License.txt for a disclaimer of all warranties
// and licensing information

#include <stdafx.h>
#include "CPU6510.h"
#include <iostream>
using namespace std;

const CPU6510::Opcodes CPU6510::m_Opcodes[256] = {
	/*0x00*/			{ &CPU6510::BRK,				NULL,						NULL,						1, 7 },
	/*0x01*/			{ &CPU6510::ORA,				&CPU6510::LoadIndirectX,	NULL,						2, 6 },
	/*0x02*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 1 },
	/*0x03*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 8 },
	/*0x04*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 3 },
	/*0x05*/			{ &CPU6510::ORA,				&CPU6510::LoadZeroPage,		NULL,						2, 3 },
	/*0x06*/			{ &CPU6510::ASL,				&CPU6510::LoadZeroPage,		&CPU6510::StoreZeroPage,	2, 5 },
	/*0x07*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 5 },
	/*0x08*/			{ &CPU6510::PHP,				NULL,						NULL,						1, 3 },
	/*0x09*/			{ &CPU6510::ORA,				&CPU6510::LoadImmediate,	NULL,						2, 3 },
	/*0x0a*/			{ &CPU6510::ASL,				&CPU6510::LoadAccumulator,	&CPU6510::StoreAccumulator,	1, 2 },
	/*0x0b*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 2 },
	/*0x0c*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 4 },
	/*0x0d*/			{ &CPU6510::ORA,				&CPU6510::LoadAbsolute,		NULL,						3, 4 },
	/*0x0e*/			{ &CPU6510::ASL,				&CPU6510::LoadAbsolute,		&CPU6510::StoreAbsolute,	3, 6 },
	/*0x0f*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 6 },
	/*0x10*/			{ &CPU6510::BPL,				NULL,						NULL,						2, 2 },
	/*0x11*/			{ &CPU6510::ORA,				&CPU6510::LoadIndirectY,	NULL,						2, 5 },
	/*0x12*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 1 },
	/*0x13*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 8 },
	/*0x14*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 4 },
	/*0x15*/			{ &CPU6510::ORA,				&CPU6510::LoadZeroPageX,	NULL,						2, 4 },
	/*0x16*/			{ &CPU6510::ASL,				&CPU6510::LoadZeroPageX,	&CPU6510::StoreZeroPageX,	2, 6 },
	/*0x17*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 6 },
	/*0x18*/			{ &CPU6510::CLC,				NULL,						NULL,						1, 2 },
	/*0x19*/			{ &CPU6510::ORA,				&CPU6510::LoadAbsoluteY,	NULL,						3, 4 },
	/*0x1a*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 2 },
	/*0x1b*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 7 },
	/*0x1c*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 4 },
	/*0x1d*/			{ &CPU6510::ORA,				&CPU6510::LoadAbsoluteX,	NULL,						3, 4 },
	/*0x1e*/			{ &CPU6510::ASL,				&CPU6510::LoadAbsoluteX,	&CPU6510::StoreAbsoluteX,	3, 7 },
	/*0x1f*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 7 },
	/*0x20*/			{ &CPU6510::JSR,				&CPU6510::LoadAbsolute,		NULL,						3, 6 },
	/*0x21*/			{ &CPU6510::AND,				&CPU6510::LoadIndirectX,	NULL,						2, 6 },
	/*0x22*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 1 },
	/*0x23*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 8 },
	/*0x24*/			{ &CPU6510::BIT,				&CPU6510::LoadZeroPage,		NULL,						2, 3 },
	/*0x25*/			{ &CPU6510::AND,				&CPU6510::LoadZeroPage,		NULL,						2, 3 },
	/*0x26*/			{ &CPU6510::ROL,				&CPU6510::LoadZeroPage,		&CPU6510::StoreZeroPage,	2, 5 },
	/*0x27*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 5 },
	/*0x28*/			{ &CPU6510::PLP,				NULL,						NULL,						1, 4 },
	/*0x29*/			{ &CPU6510::AND,				&CPU6510::LoadImmediate,	NULL,						2, 2 },
	/*0x2a*/			{ &CPU6510::ROL,				&CPU6510::LoadAccumulator,	NULL,						1, 2 },
	/*0x2b*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 2 },
	/*0x2c*/			{ &CPU6510::BIT,				&CPU6510::LoadAbsolute,		NULL,						3, 4 },
	/*0x2d*/			{ &CPU6510::AND,				&CPU6510::LoadAbsolute,		NULL,						3, 4 },
	/*0x2e*/			{ &CPU6510::ROL,				&CPU6510::LoadAbsolute,		&CPU6510::StoreAbsolute,	3, 6 },
	/*0x2f*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 6 },
	/*0x30*/			{ &CPU6510::BMI,				&CPU6510::LoadRelative,		NULL,						2, 2 },
	/*0x31*/			{ &CPU6510::AND,				&CPU6510::LoadIndirectY,	NULL,						2, 5 },
	/*0x32*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 1 },
	/*0x33*/			{ &NotImplemented,				NULL,						NULL,						2, 8 },
	/*0x34*/			{ &NotImplemented,				NULL,						NULL,						2, 4 },
	/*0x35*/			{ &CPU6510::AND,				&CPU6510::LoadZeroPageX,	NULL,						2, 4 },
	/*0x36*/			{ &CPU6510::ROL,				&CPU6510::LoadZeroPageX,	&CPU6510::StoreZeroPageX,	2, 6 },
	/*0x37*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 6 },	
	/*0x38*/			{ &CPU6510::SEC,				NULL,						NULL,						1, 2 },
	/*0x39*/			{ &CPU6510::AND,				&CPU6510::LoadAbsoluteY,	NULL,						3, 4 },
	/*0x3a*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 2 },
	/*0x3b*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 7 },
	/*0x3c*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 4 },
	/*0x3d*/			{ &CPU6510::AND,				&CPU6510::LoadAbsoluteX,	NULL,						3, 4 },
	/*0x3e*/			{ &CPU6510::ROL,				&CPU6510::LoadAbsoluteX,	NULL,						3, 7 },
	/*0x3f*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 7 },
	/*0x40*/			{ &CPU6510::RTI,				NULL,						NULL,						1, 6 },
	/*0x41*/			{ &CPU6510::EOR,				&CPU6510::LoadIndirectX,	NULL,						2, 6 },
	/*0x42*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 1 },
	/*0x43*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 8 },
	/*0x44*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 3 },				
	/*0x45*/			{ &CPU6510::EOR,				&CPU6510::LoadZeroPage,		NULL,						2, 3 },
	/*0x46*/			{ &CPU6510::LSR,				&CPU6510::LoadZeroPage,		&CPU6510::StoreZeroPage,	2, 7 },
	/*0x47*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 5 },
	/*0x48*/			{ &CPU6510::PHA,				NULL,						NULL,						1, 3 },
	/*0x49*/			{ &CPU6510::EOR,				&CPU6510::LoadImmediate,	NULL,						2, 2 },
	/*0x4a*/			{ &CPU6510::LSR,				&CPU6510::LoadAccumulator,	&CPU6510::StoreAccumulator,	1, 2 },
	/*0x4b*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 2 },
	/*0x4c*/			{ &CPU6510::JMP,				&CPU6510::LoadAbsolute,		NULL,						3, 3 },
	/*0x4d*/			{ &CPU6510::EOR,				&CPU6510::LoadAbsolute,		NULL,						3, 4 },
	/*0x4e*/			{ &CPU6510::LSR,				&CPU6510::LoadAbsolute,		&CPU6510::StoreAbsolute,	3, 6 },
	/*0x4f*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 6 },
	/*0x50*/			{ &CPU6510::BVC,				&CPU6510::LoadRelative,		NULL,						2, 2 },
	/*0x51*/			{ &CPU6510::EOR,				&CPU6510::LoadIndirectY,	NULL,						2, 5 },
	/*0x52*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 1 }, 
	/*0x53*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 8 },
	/*0x54*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 4 },
	/*0x55*/			{ &CPU6510::EOR,				&CPU6510::LoadZeroPageX,	NULL,						2, 4 },
	/*0x56*/			{ &CPU6510::LSR,				&CPU6510::LoadZeroPageX,	&CPU6510::StoreZeroPageX,	2, 6 },
	/*0x57*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 6 },
	/*0x58*/			{ &CPU6510::CLI,				NULL,						NULL,						1, 2 },
	/*0x59*/			{ &CPU6510::EOR,				&CPU6510::LoadAbsoluteY,	NULL,						3, 4 },
	/*0x5a*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 2 },				
	/*0x5b*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 7 },
	/*0x5c*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 4 },
	/*0x5d*/			{ &CPU6510::EOR,				&CPU6510::LoadAbsoluteX,	NULL,						3, 4 },
	/*0x5e*/			{ &CPU6510::LSR,				&CPU6510::LoadAbsoluteX,	&CPU6510::StoreAbsoluteX,	3, 7 },
	/*0x5f*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 7 },
	/*0x60*/			{ &CPU6510::RTS,				NULL,						NULL,						1, 6 },
	/*0x61*/			{ &CPU6510::ADC,				&CPU6510::LoadIndirectX,	NULL,						2, 6 },
	/*0x62*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 1 },
	/*0x63*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 8 },
	/*0x64*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 3 },
	/*0x65*/			{ &CPU6510::ADC,				&CPU6510::LoadZeroPage,		NULL,						2, 3 },
	/*0x66*/			{ &CPU6510::ROR,				&CPU6510::LoadZeroPage,		&CPU6510::StoreZeroPage,	2, 5 },
	/*0x67*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 5 },
	/*0x68*/			{ &CPU6510::PLA,				NULL,						NULL,						1, 4 },
	/*0x69*/			{ &CPU6510::ADC,				&CPU6510::LoadImmediate,	NULL,						2, 2 },
	/*0x6a*/			{ &CPU6510::ROR,				&CPU6510::LoadAccumulator,	&CPU6510::StoreAccumulator,	1, 2 },
	/*0x6b*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 2 },
	/*0x6c*/			{ &CPU6510::JMP,				&CPU6510::LoadIndirect,		NULL,						3, 5 },
	/*0x6d*/			{ &CPU6510::ADC,				&CPU6510::LoadAbsolute,		NULL,						3, 4 },
	/*0x6e*/			{ &CPU6510::ROR,				&CPU6510::LoadAbsolute,		&CPU6510::StoreAbsolute,	3, 6 },
	/*0x6f*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 6 },
	/*0x70*/			{ &CPU6510::BVS,				&CPU6510::LoadRelative,		NULL,						2, 2 },
	/*0x71*/			{ &CPU6510::ADC,				&CPU6510::LoadIndirectY,	NULL,						2, 5 },
	/*0x72*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 1 },
	/*0x73*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 8 },
	/*0x74*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 4 },
	/*0x75*/			{ &CPU6510::ADC,				&CPU6510::LoadZeroPageX,	NULL,						2, 4 },
	/*0x76*/			{ &CPU6510::ROR,				&CPU6510::LoadZeroPageX,	&CPU6510::StoreZeroPageX,	2, 6 },
	/*0x77*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 6 },
	/*0x78*/			{ &CPU6510::SEI,				NULL,						NULL,						1, 2 },
	/*0x79*/			{ &CPU6510::ADC,				&CPU6510::LoadAbsoluteY,	NULL,						3, 4 },	
	/*0x7a*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 2 },
	/*0x7b*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 7 },
	/*0x7c*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 4 },
	/*0x7d*/			{ &CPU6510::ADC,				&CPU6510::LoadAbsoluteX,	NULL,						3, 4 },
	/*0x7e*/			{ &CPU6510::ROR,				&CPU6510::LoadAbsoluteX,	&CPU6510::StoreAbsoluteX,	3, 7 },
	/*0x7f*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 7 },
	/*0x80*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 2 },
	/*0x81*/			{ &CPU6510::STA,				NULL,						&CPU6510::StoreIndirectX,	2, 6 },
	/*0x82*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 2 },
	/*0x83*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 6 },
	/*0x84*/			{ &CPU6510::STY,				NULL,						&CPU6510::StoreZeroPage,	2, 3 },
	/*0x85*/			{ &CPU6510::STA,				NULL,						&CPU6510::StoreZeroPage,	2, 3 },
	/*0x86*/			{ &CPU6510::STX,				NULL,						&CPU6510::StoreZeroPage,	2, 3 },
	/*0x87*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 3 },
	/*0x88*/			{ &CPU6510::DEY,				NULL,						NULL,						1, 2 },
	/*0x89*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 2 },
	/*0x8a*/			{ &CPU6510::TXA,				NULL,						NULL,						1, 2 },
	/*0x8b*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 2 },
	/*0x8c*/			{ &CPU6510::STY,				NULL,						&CPU6510::StoreAbsolute,	3, 4 },
	/*0x8d*/			{ &CPU6510::STA,				NULL,						&CPU6510::StoreAbsolute,	3, 4 },
	/*0x8e*/			{ &CPU6510::STX,				NULL,						&CPU6510::StoreAbsolute,	3, 4 },
	/*0x8f*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 4 },
	/*0x90*/			{ &CPU6510::BCC,				&CPU6510::LoadRelative,		NULL,						2, 2 },
	/*0x91*/			{ &CPU6510::STA,				NULL,						&CPU6510::StoreIndirectY,	2, 6 },
	/*0x92*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 1 },
	/*0x93*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 6 },
	/*0x94*/			{ &CPU6510::STY,				NULL,						&CPU6510::StoreZeroPageX,	2, 4 },
	/*0x95*/			{ &CPU6510::STA,				NULL,						&CPU6510::StoreZeroPageX,	2, 4 },
	/*0x96*/			{ &CPU6510::STX,				NULL,						&CPU6510::StoreZeroPageY,	2, 4 },
	/*0x97*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 4 },
	/*0x98*/			{ &CPU6510::TYA,				NULL,						NULL,						1, 2 },
	/*0x99*/			{ &CPU6510::STA,				NULL,						&CPU6510::StoreAbsoluteY,	3, 5 },
	/*0x9a*/			{ &CPU6510::TXS,				NULL,						NULL,						1, 2 },
	/*0x9b*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 5 },
	/*0x9c*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 5 },
	/*0x9d*/			{ &CPU6510::STA,				NULL,						&CPU6510::StoreAbsoluteX,	3, 5 },
	/*0x9e*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 5 },
	/*0x9f*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 5 },
	/*0xa0*/			{ &CPU6510::LDY,				&CPU6510::LoadImmediate,	NULL,						2, 2 },
	/*0xa1*/			{ &CPU6510::LDA,				&CPU6510::LoadIndirectX,	NULL,						2, 6 },
	/*0xa2*/			{ &CPU6510::LDX,				&CPU6510::LoadImmediate,	NULL,						2, 2 },
	/*0xa3*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 6 },
	/*0xa4*/			{ &CPU6510::LDY,				&CPU6510::LoadZeroPage,		NULL,						2, 3 },
	/*0xa5*/			{ &CPU6510::LDA,				&CPU6510::LoadZeroPage,		NULL,						2, 3 },
	/*0xa6*/			{ &CPU6510::LDX,				&CPU6510::LoadZeroPage,		NULL,						2, 3 },
	/*0xa7*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 3 },
	/*0xa8*/			{ &CPU6510::TAY,				NULL,						NULL,						1, 2 },
	/*0xa9*/			{ &CPU6510::LDA,				&CPU6510::LoadImmediate,	NULL,						2, 2 },
	/*0xaa*/			{ &CPU6510::TAX,				NULL,						NULL,						1, 2 },
	/*0xab*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 2 },
	/*0xac*/			{ &CPU6510::LDY,				&CPU6510::LoadAbsolute,		NULL,						3, 4 },
	/*0xad*/			{ &CPU6510::LDA,				&CPU6510::LoadAbsolute,		NULL,						3, 4 },
	/*0xae*/			{ &CPU6510::LDX,				&CPU6510::LoadAbsolute,		NULL,						3, 4 },
	/*0xaf*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 4 },
	/*0xb0*/			{ &CPU6510::BCS,				&CPU6510::LoadRelative,		NULL,						2, 2 },
	/*0xb1*/			{ &CPU6510::LDA,				&CPU6510::LoadIndirectY,	NULL,						2, 5 },
	/*0xb2*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 1 },
	/*0xb3*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 5 },
	/*0xb4*/			{ &CPU6510::LDY,				&CPU6510::LoadZeroPageX,	NULL,						2, 4 },
	/*0xb5*/			{ &CPU6510::LDA,				&CPU6510::LoadZeroPageX,	NULL,						2, 4 },
	/*0xb6*/			{ &CPU6510::LDX,				&CPU6510::LoadZeroPageY,	NULL,						2, 4 },
	/*0xb7*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 4 },
	/*0xb8*/			{ &CPU6510::CLV,				NULL,						NULL,						1, 2 },
	/*0xb9*/			{ &CPU6510::LDA,				&CPU6510::LoadAbsoluteY,	NULL,						3, 4 },
	/*0xba*/			{ &CPU6510::TSX,				NULL,						NULL,						1, 2 },
	/*0xbb*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 4 },
	/*0xbc*/			{ &CPU6510::LDY,				&CPU6510::LoadAbsoluteX,	NULL,						3, 4 },
	/*0xbd*/			{ &CPU6510::LDA,				&CPU6510::LoadAbsoluteX,	NULL,						3, 4 },
	/*0xbe*/			{ &CPU6510::LDX,				&CPU6510::LoadAbsoluteY,	NULL,						3, 4 },
	/*0xbf*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 4 },
	/*0xc0*/			{ &CPU6510::CPY,				&CPU6510::LoadImmediate,	NULL,						2, 2 },
	/*0xc1*/			{ &CPU6510::CMP,				&CPU6510::LoadIndirectX,	NULL,						2, 6 },
	/*0xc2*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 2 },
	/*0xc3*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 8 },
	/*0xc4*/			{ &CPU6510::CPY,				&CPU6510::LoadZeroPage,		NULL,						2, 3 },
	/*0xc5*/			{ &CPU6510::CMP,				&CPU6510::LoadZeroPage,		NULL,						2, 3 },
	/*0xc6*/			{ &CPU6510::DEC,				&CPU6510::LoadZeroPage,		&CPU6510::StoreZeroPage,	2, 5 },
	/*0xc7*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 5 },
	/*0xc8*/			{ &CPU6510::INY,				NULL,						NULL,						1, 2 },
	/*0xc9*/			{ &CPU6510::CMP,				&CPU6510::LoadImmediate,	NULL,						2, 2 },
	/*0xca*/			{ &CPU6510::DEX,				NULL,						NULL,						1, 2 },
	/*0xcb*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 2 },
	/*0xcc*/			{ &CPU6510::CPY,				&CPU6510::LoadAbsolute,		NULL,						3, 4 },
	/*0xcd*/			{ &CPU6510::CMP,				&CPU6510::LoadAbsolute,		NULL,						3, 4 },
	/*0xce*/			{ &CPU6510::DEC,				&CPU6510::LoadAbsolute,		&CPU6510::StoreAbsolute,	3, 6 },
	/*0xcf*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 6 },
	/*0xd0*/			{ &CPU6510::BNE,				&CPU6510::LoadRelative,		NULL,						2, 2 },
	/*0xd1*/			{ &CPU6510::CMP,				&CPU6510::LoadIndirectY,	NULL,						2, 5 },
	/*0xd2*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 1 },
	/*0xd3*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 8 },
	/*0xd4*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 4 },
	/*0xd5*/			{ &CPU6510::CMP,				&CPU6510::LoadZeroPageX,	NULL,						2, 4 },
	/*0xd6*/			{ &CPU6510::DEC,				&CPU6510::LoadZeroPageX,	&CPU6510::StoreZeroPageX,	2, 6 },
	/*0xd7*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 6 },
	/*0xd8*/			{ &CPU6510::CLD,				NULL,						NULL,						1, 2 },
	/*0xd9*/			{ &CPU6510::CMP,				&CPU6510::LoadAbsoluteY,	NULL,						3, 4 },
	/*0xda*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 2 },
	/*0xdb*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 7 },
	/*0xdc*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 4 },
	/*0xdd*/			{ &CPU6510::CMP,				&CPU6510::LoadAbsoluteX,	NULL,						3, 4 },
	/*0xde*/			{ &CPU6510::DEC,				&CPU6510::LoadAbsoluteX,	&CPU6510::StoreAbsoluteX,	3, 7 },
	/*0xdf*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 7 },
	/*0xe0*/			{ &CPU6510::CPX,				&CPU6510::LoadImmediate,	NULL,						2, 2 },
	/*0xe1*/			{ &CPU6510::SBC,				&CPU6510::LoadIndirectX,	NULL,						2, 6 },
	/*0xe2*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 2 },
	/*0xe3*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 8 },
	/*0xe4*/			{ &CPU6510::CPX,				&CPU6510::LoadZeroPage,		NULL,						2, 3 },
	/*0xe5*/			{ &CPU6510::SBC,				&CPU6510::LoadZeroPage,		NULL,						2, 3 },
	/*0xe6*/			{ &CPU6510::INC,				&CPU6510::LoadZeroPage,		&CPU6510::StoreZeroPage,	2, 5 },
	/*0xe7*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 5 },
	/*0xe8*/			{ &CPU6510::INX,				NULL,						NULL,						1, 2 },
	/*0xe9*/			{ &CPU6510::SBC,				&CPU6510::LoadImmediate,	NULL,						2, 2 },
	/*0xea*/			{ &CPU6510::NOP,				NULL,						NULL,						1, 2 },
	/*0xeb*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 2 },
	/*0xec*/			{ &CPU6510::SBC,				&CPU6510::LoadAbsolute,		NULL,						3, 4 },
	/*0xed*/			{ &CPU6510::CPX,				&CPU6510::LoadAbsolute,		NULL,						3, 4 },
	/*0xee*/			{ &CPU6510::INC,				&CPU6510::LoadAbsolute,		&CPU6510::StoreAbsolute,	3, 6 },
	/*0xef*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 6 },
	/*0xf0*/			{ &CPU6510::BEQ,				&CPU6510::LoadRelative,		NULL,						2, 2 },
	/*0xf1*/			{ &CPU6510::SBC,				&CPU6510::LoadIndirectY,	NULL,						2, 5 },
	/*0xf2*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 1 },
	/*0xf3*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 8 },
	/*0xf4*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 4 },
	/*0xf5*/			{ &CPU6510::SBC,				&CPU6510::LoadZeroPageX,	NULL,						2, 4 },
	/*0xf6*/			{ &CPU6510::INC,				&CPU6510::LoadZeroPageX,	&CPU6510::StoreZeroPageX,	2, 6 },
	/*0xf7*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 6 },
	/*0xf8*/			{ &CPU6510::SED,				NULL,						NULL,						1, 2 },
	/*0xf9*/			{ &CPU6510::SBC,				&CPU6510::LoadAbsoluteY,	NULL,						3, 4 },
	/*0xfa*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						1, 2 },
	/*0xfb*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						2, 7 },
	/*0xfc*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 4 },
	/*0xfd*/			{ &CPU6510::SBC,				&CPU6510::LoadAbsoluteX,	NULL,						3, 4 },
	/*0xfe*/			{ &CPU6510::INC,				&CPU6510::LoadAbsoluteX,	&CPU6510::StoreAbsolute,	3, 7 },
	/*0xff*/			{ &CPU6510::NotImplemented,		NULL,						NULL,						3, 7 }
	};

void CPU6510::Push(unsigned char byValue)
{
	SetMemory(0x100 + SP, byValue);
	if (SR)
		SR--;
}

unsigned char CPU6510::Pop()
{
	if (SR < 0xff)
		SR++;
	return GetMemory(0x100 + SR);
	return 0; //temp
}

void CPU6510::SetFlag(unsigned char kFlag, int nVal)
{
	nVal ? SR |= kFlag : SR = SR & ~kFlag;
}

void CPU6510::Branch()
{
	unsigned char byTemp1;
	signed char cTemp2;

	m_ulClock++;
	byTemp1 = m_pCurrentMemory[1];

	if (byTemp1 & kFlag_N) //If negative flag is on
		cTemp2 = -(byTemp1 ^ 0xff) - 1;
	else
		cTemp2 = byTemp1;

	if (((PC + cTemp2) >> 8) != PC >> 8)
		m_ulClock++;
		
	PC += cTemp2;
}

void CPU6510::ADC()
{
	unsigned short wTemp1;
	unsigned char byTemp2 = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) ();

	wTemp1 = byTemp2 + A + ((SR & kFlag_C) ? 1 : 0); //Add the source address with the accumulator also taking into account the carry
	
	A = static_cast<unsigned char>(wTemp1);
	SetFlag(kFlag_C, wTemp1 & 0x0100);
	SetFlag(kFlag_Z, !A);
	SetFlag(kFlag_N, A & 0x80);
	SetFlag(kFlag_V, (!!(SR & kFlag_C)) ^ (!!(SR & kFlag_N))); //Might not need this in adding as overflow is not counted
}

void CPU6510::AND()
{
	unsigned char byTemp = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) ();
	A &= byTemp;
	SetFlag(kFlag_Z, !A);
	SetFlag(kFlag_N, A & 0x80);
}

void CPU6510::ASL()
{
	unsigned char bySrc = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) ();
	bySrc = bySrc << 1;
	(this->*(m_Opcodes[*m_pCurrentMemory].StoreAddress)) (bySrc);
	SetFlag(kFlag_Z, ~bySrc);
	SetFlag(kFlag_C, bySrc & 0x0100);
	SetFlag(kFlag_N, bySrc & 0x800);


}

void CPU6510::BCC()
{
	if (!(SR & kFlag_C))
		Branch();
}

void CPU6510::BCS()
{
	if (SR & kFlag_C)
		Branch();
}

void CPU6510::BEQ()
{
	if (SR & kFlag_Z)
		Branch();
}

void CPU6510::BIT()
{
	unsigned char bySrc = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) ();
	SetFlag(kFlag_Z, !(A & bySrc));
	SetFlag(kFlag_N, bySrc & kFlag_N);
	SetFlag(kFlag_V, bySrc & kFlag_V);
}

void CPU6510::BMI()
{
	if (SR & kFlag_N)
		Branch();
}

void CPU6510::BNE()
{
	if (!(SR & kFlag_Z))
		Branch();
}

void CPU6510::BRK()
{
	//Just exit here no intterupt
	PC = 0;
}

void CPU6510::BPL()
{
	if (!(SR & kFlag_N))
		Branch();
}

void CPU6510::BVC()
{
	if (!(SR & kFlag_Z))
		Branch();
}

void CPU6510::BVS()
{
	if (SR & kFlag_Z)
		Branch();
}

void CPU6510::CLC()
{
	SetFlag(kFlag_C, 0);
}

void CPU6510::CLD()
{
	SetFlag(kFlag_D, 0);
}

void CPU6510::CLI()
{
	SetFlag(kFlag_I, 0);
}

void CPU6510::CLV()
{
	SetFlag(kFlag_V, 0);
}

void CPU6510::CMP()
{
	//Lets do this differant?
	unsigned char byTemp1; 
	unsigned short wTemp2;
	byTemp1 = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) ();
	wTemp2 = A - byTemp1;

	SetFlag(kFlag_Z, !wTemp2);
	SetFlag(kFlag_N, wTemp2 & kFlag_N);
	SetFlag(kFlag_C, A >= byTemp1);
}

void CPU6510::CPX()
{
	unsigned char byTemp1;
	unsigned short wTemp2;

	byTemp1 = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) ();
	wTemp2 = X - byTemp1;

	SetFlag(kFlag_Z, !wTemp2);
	SetFlag(kFlag_N, wTemp2 & kFlag_N);
	SetFlag(kFlag_C, X >= byTemp1);
}

void CPU6510::CPY()
{
	unsigned char byTemp1;
	unsigned short wTemp2;

	byTemp1 = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) ();
	wTemp2 = Y - byTemp1;

	SetFlag(kFlag_Z, !wTemp2);
	SetFlag(kFlag_N, wTemp2 & kFlag_N);
	SetFlag(kFlag_C, Y >= byTemp1);
}

void CPU6510::DEC()
{
	unsigned char byTemp1 = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) ();
	byTemp1--;
	(this->*(m_Opcodes[*m_pCurrentMemory].StoreAddress)) (byTemp1);

	SetFlag(kFlag_Z, !byTemp1);
	SetFlag(kFlag_N, byTemp1 & kFlag_N);
}

void CPU6510::DEX()
{
	X--;
	SetFlag(kFlag_Z, !X);
	SetFlag(kFlag_N, X & kFlag_N);
}

void CPU6510::DEY()
{
	Y--;
	SetFlag(kFlag_Z, !Y);
	SetFlag(kFlag_N, Y & kFlag_N);
}

void CPU6510::EOR()
{
	unsigned char byTemp1 = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) ();
	A ^= byTemp1;

	SetFlag(kFlag_Z, !A);
	SetFlag(kFlag_N, A & kFlag_N);
}

void CPU6510::INC()
{
	unsigned char byTemp1 = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) ();
	byTemp1++;
	(this->*(m_Opcodes[*m_pCurrentMemory].StoreAddress)) (byTemp1);

	SetFlag(kFlag_Z, !byTemp1);
	SetFlag(kFlag_N, byTemp1 & kFlag_N);

}

void CPU6510::INX()
{
	X++;

	SetFlag(kFlag_Z, !X);
	SetFlag(kFlag_N, X & kFlag_N);
}

void CPU6510::INY()
{
	Y++;

	SetFlag(kFlag_Z, !Y);
	SetFlag(kFlag_N, Y & kFlag_N);
}

void CPU6510::JMP()
{
	if ((this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) == &CPU6510::LoadIndirect) //If it is Indirect
		PC = m_byMemory[m_pCurrentMemory[1] + (m_byMemory[m_pCurrentMemory[2] + 1] << 8)];
	else //Its absolute;
		PC = m_pCurrentMemory[1] + (m_pCurrentMemory[2] << 8);
}

void CPU6510::JSR()
{
	PC += 2;
	Push(PC & 0xff);
	Push(PC >> 8);
	PC = m_pCurrentMemory[1] + (m_pCurrentMemory[2] << 8);

}

void CPU6510::LDA()
{
	A = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) ();

	SetFlag(kFlag_Z, !A);
	SetFlag(kFlag_N, A & kFlag_N);
}

void CPU6510::LDX()
{
	X = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) ();

	SetFlag(kFlag_Z, !X);
	SetFlag(kFlag_N, X & kFlag_N);
}

void CPU6510::LDY()
{
	Y = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) ();

	SetFlag(kFlag_Z, !Y);
	SetFlag(kFlag_N, X & kFlag_N);
}

void CPU6510::LSR()
{
	unsigned char byTemp1 = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) ();
	unsigned short wTemp2  = byTemp1;

	wTemp2 <<= 1;
	(this->*(m_Opcodes[*m_pCurrentMemory].StoreAddress)) (static_cast<unsigned char>(wTemp2));

	SetFlag(kFlag_Z, !wTemp2);
	SetFlag(kFlag_N, kFlag_N & wTemp2);
	SetFlag(kFlag_C, byTemp1 & 1);
}

void CPU6510::NOP()
{
	//Do nothing the cycles and pc will increment themselves
}

void CPU6510::ORA()
{
	unsigned char byTemp1 = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) ();
	A |= byTemp1;

	SetFlag(kFlag_Z, !A);
	SetFlag(kFlag_N, kFlag_N & A);

}

void CPU6510::PHA()
{
	Push(A);
}

void CPU6510::PHP()
{
	Push(SR);
}

void CPU6510::PLA()
{
	A = Pop();

	SetFlag(kFlag_Z, !A);
	SetFlag(kFlag_N, kFlag_N & A);
}

void CPU6510::PLP()
{
	SR = Pop();
}

void CPU6510::ROL()
{
	unsigned char byTemp1 = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) ();
	unsigned char byTemp2 = SR & kFlag_C; //Issolate the carry bit if it is needed
	unsigned char byTemp3 = (byTemp1 << 1) + byTemp2; //Perform the shift and add carry bit if needed

	if (byTemp1 & kFlag_N) //If its a large value
		SetFlag(kFlag_C, 1); // Set the carry flag
	else
		SR &= 0xFE; //Capture all the bits except the carry which sould be zero, could change to !k_Flag_C?
	
	SetFlag(kFlag_N, !byTemp3);
	SetFlag(kFlag_Z, byTemp3 & kFlag_Z);

	(this->*(m_Opcodes[*m_pCurrentMemory].StoreAddress)) (byTemp3);

}

void CPU6510::ROR()
{
	unsigned char byTemp1 = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) ();
	unsigned char byTemp2 = SR & kFlag_C; //Issolate the carry bit;
	unsigned char byTemp3 = (byTemp1 << 1) + byTemp2;

	if (byTemp1 & kFlag_C)
		SetFlag(kFlag_C, 1);
	else
		SR &= 0xFE; //Could use !kFlag_C
}

void CPU6510::RTI()
{
	//Needs to be looked at? TODO
}

void CPU6510::RTS()
{
	unsigned short wTemp1 = Pop();
	wTemp1 |= (Pop() << 8);
	PC = wTemp1 + 1;
}

void CPU6510::SBC()
{
	unsigned char byTemp1 = (this->*(m_Opcodes[*m_pCurrentMemory].LoadAddress)) () ^ 0xff; //Inverts the byte
	unsigned short wTemp2 = A + byTemp1 + ((SR & kFlag_C) ? 1 : 0);
	
	A = static_cast<unsigned char>(wTemp2);
	SetFlag(kFlag_C, wTemp2 & 0x100);
	SetFlag(kFlag_Z, !wTemp2);
	SetFlag(kFlag_N, wTemp2 & kFlag_N);
	SetFlag(kFlag_V, (!!(SR & kFlag_C)) ^ (!!(SR & kFlag_N)));

}

void CPU6510::SEC()
{
	SetFlag(kFlag_C, 1);
}

void CPU6510::SED()
{
	SetFlag(kFlag_D, 1);
}

void CPU6510::SEI()
{
	SetFlag(kFlag_I, 1);
}

void CPU6510::STA()
{
	(this->*(m_Opcodes[*m_pCurrentMemory].StoreAddress))(A);
}

void CPU6510::STX()
{
	(this->*(m_Opcodes[*m_pCurrentMemory].StoreAddress))(X);
}

void CPU6510::STY()
{
	(this->*(m_Opcodes[*m_pCurrentMemory].StoreAddress))(Y);
}

void CPU6510::TAX()
{
	X = A;

	SetFlag(kFlag_Z, !X);
	SetFlag(kFlag_N, X & kFlag_N);
}

void CPU6510::TAY()
{
	Y = A;
	
	SetFlag(kFlag_Z, !Y);
	SetFlag(kFlag_N, Y & kFlag_N);
}

void CPU6510::TSX()
{
	X = SP;
	
	SetFlag(kFlag_Z, !X);
	SetFlag(kFlag_N, X & kFlag_N);
}

void CPU6510::TXA()
{
	A = X;

	SetFlag(kFlag_Z, !A);
	SetFlag(kFlag_N, A & kFlag_N);

}

void CPU6510::TXS()
{
	SP = X;
}

void CPU6510::TYA()
{
	A = Y;

	SetFlag(kFlag_Z, !A);
	SetFlag(kFlag_N, A & kFlag_N);
}

void CPU6510::NotImplemented()
{
	//Non implemented opcode;
}

unsigned char CPU6510::LoadAbsolute()
{
	return m_byMemory[m_pCurrentMemory[1] + ( m_pCurrentMemory[2] << 8)];
}

unsigned char CPU6510::LoadAbsoluteX()
{
	return m_byMemory[m_pCurrentMemory[1] +( m_pCurrentMemory[2] << 8 ) + X];
}

unsigned char CPU6510::LoadAbsoluteY()
{
	return m_byMemory[m_pCurrentMemory[1] + ( m_pCurrentMemory[2] << 8) + Y];
}

unsigned char CPU6510::LoadAccumulator()
{
	return A;
}

unsigned char CPU6510::LoadImmediate()
{
	return m_byMemory[m_pCurrentMemory[1]];
}

unsigned char CPU6510::LoadIndirect()
{
	
	return 0; //JMP uses this need to know?
}

unsigned char CPU6510::LoadIndirectX()
{
	unsigned char byTemp;
	m_pCurrentMemory += X;
	byTemp = m_byMemory[m_byMemory[m_pCurrentMemory[1] + (m_pCurrentMemory[2] << 8)]];
	m_pCurrentMemory -= X;
	return byTemp;
}

unsigned char CPU6510::LoadIndirectY()
{
	return m_byMemory[m_byMemory[m_pCurrentMemory[1] + (m_pCurrentMemory[2] << 8)] + Y];
}

unsigned char CPU6510::LoadRelative()
{
	return m_pCurrentMemory[1];
}

unsigned char CPU6510::LoadZeroPage()
{
	return m_byMemory[m_pCurrentMemory[1]];
}

unsigned char CPU6510::LoadZeroPageX()
{
	return m_byMemory[m_pCurrentMemory[1] + X];
}

unsigned char CPU6510::LoadZeroPageY()
{
	return m_byMemory[m_pCurrentMemory[1] + Y];
}

void CPU6510::StoreAbsolute(unsigned char byValue)
{
	m_byMemory[m_pCurrentMemory[1] + (m_pCurrentMemory[2] << 8)] = byValue;
}

void CPU6510::StoreAbsoluteX(unsigned char byValue)
{
	m_byMemory[m_pCurrentMemory[1] + (m_pCurrentMemory[2] << 8)] = byValue;
}

void CPU6510::StoreAbsoluteY(unsigned char byValue)
{
	m_byMemory[m_pCurrentMemory[1] + (m_pCurrentMemory[2] << 8)] = byValue;
}

void CPU6510::StoreAccumulator(unsigned char byValue)
{
	A = byValue;
}

void CPU6510::StoreImmediate(unsigned char byValue)
{
	
}

void CPU6510::StoreIndirect(unsigned char byValue)
{

}

void CPU6510::StoreIndirectX(unsigned char byValue)
{
	m_pCurrentMemory += X;
	m_byMemory[m_byMemory[m_pCurrentMemory[1] + (m_pCurrentMemory[2] << 8)]] = byValue;
	m_pCurrentMemory -= X;
}

void CPU6510::StoreIndirectY(unsigned char byValue)
{
	m_byMemory[m_byMemory[m_pCurrentMemory[1] + (m_pCurrentMemory[2] << 8)] + Y] = byValue;
}

void CPU6510::StoreRelative(unsigned char byValue)
{

}

void CPU6510::StoreZeroPage(unsigned char byValue)
{
	m_byMemory[m_pCurrentMemory[1]] = byValue;
}

void CPU6510::StoreZeroPageX(unsigned char byValue)
{
	m_byMemory[m_pCurrentMemory[1] + X] = byValue;
}

void CPU6510::StoreZeroPageY(unsigned char byValue)
{
	m_byMemory[m_pCurrentMemory[1] + Y] = byValue;
}

CPU6510::CPU6510(RWSID *pSID)
{
	m_pSID = pSID;
	Init();
}

CPU6510::~CPU6510()
{
	//Not really needed but used anyway?
}

void CPU6510::Init()
{
	m_fClockFreq = 985248.f; //I am just setting this to pal for the time being cause i am lazy should look into ntsc
	memset(&m_byMemory, 0, sizeof(m_byMemory)); //Checking naughty naughty :)
	Reset();

}

void CPU6510::Reset()
{
	A = X = Y = 0;
	SR = 0;
	SP = 0xff;
	PC = m_byMemory[0xfffc] + (m_byMemory[0xfffd] << 8); //This is the power on for the c64 and is not really useful as there is no rom loaded
	m_pCurrentMemory = m_byMemory + PC;
	m_ulClock = 0;
}

unsigned long CPU6510::Execute(unsigned int nInstructions)
{
	unsigned long ulCycles = 0;

	while (nInstructions > 0)
	{
		(this->*(m_Opcodes[*m_pCurrentMemory].Instruction)) (); //Decodes instruction in memory
		PC += m_Opcodes[*m_pCurrentMemory].NumBytes; // Increments the Program counter however many is needed for that instruction
		ulCycles += m_Opcodes[*m_pCurrentMemory].Cycles; //Increment the amount of cycles taken
		nInstructions--; //We have completed one instruction
		m_pCurrentMemory = m_byMemory + PC; //Set the current mem pointer to the next instruction
	}
	
	m_ulClock += ulCycles;
	return ulCycles;
}

void CPU6510::ResetTo(unsigned short wPC, unsigned char byA, unsigned char byX, unsigned char byY)
{
	PC = wPC;
	A = byA;
	X = byX;
	Y = byY;
	SR = 0;
	SP = 0xff;
	m_pCurrentMemory = m_byMemory + PC;
	m_ulClock = 0;
}

void CPU6510::SetMemory(unsigned short byAddress, unsigned char byValue)
{
	
	if ((byAddress >= 0) && (byAddress < 0xffff)) //Check that the memory address is in range
	{
		m_byMemory[byAddress] = byValue;
		if ((byAddress & 0xfc00) == 0xd400)
		{
			unsigned char byReg = byAddress & 0x001f;
			m_pSID->WriteSIDReg(byReg, byValue);
		}
	}
	else
		cout << "CPU tried to store a value on an address out of range" << endl;
	//Then we need to work out whetether it is a SID location TODO:
}

unsigned char CPU6510::GetMemory(unsigned short byAddress)
{
	if ((byAddress >= 0) && (byAddress < 0xffff))
	{
		if ((byAddress * 0xfc00) == 0xd400) //Check if its a sid address
		{
			unsigned char byReg = byReg = byAddress & 0x001f;
			return m_pSID->ReadSIDReg(byReg);
		}
		else	//if its not return the memory value
			return m_byMemory[byAddress];
	}
	else
	{
		cout << "CPU tried to access an address out of range" << endl;
		return 0;
	}

}

void CPU6510::SetClockFreq(float fClockFreq)
{
	m_fClockFreq = fClockFreq;
}

float CPU6510::GetClockFreq()
{
	return m_fClockFreq;
}

unsigned long CPU6510::GetCycles()
{
	return m_ulClock;
}
